package com.ly.juc;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Classname DeadLock
 * @Description TODO
 * @Date 2020/10/5 15:59
 * @Author 冷心影翼
 */

class Source {

	private String lockA = "lockA";

	private String lockB = "lockB";


	public void lockA() throws InterruptedException {
		synchronized(lockA){
			System.out.println(Thread.currentThread().getName() +lockB);
			TimeUnit.SECONDS.sleep(2);
			synchronized (lockB) {
				System.out.println(Thread.currentThread().getName() +lockA);
			}
		}
	}

	public void lockB() throws InterruptedException {
		synchronized(lockB){
			System.out.println(Thread.currentThread().getName() +lockA);
			TimeUnit.SECONDS.sleep(2);
			synchronized (lockA) {
				System.out.println(Thread.currentThread().getName() +lockB);
			}
		}
	}

}

public class DeadLock {

	private Lock lockA = new ReentrantLock();
	private Lock lockB = new ReentrantLock();

	public void A() {
		lockB.lock();
		lockA.lock();
		try{
			System.out.println("A is Running");
		}catch(Exception e){

		}finally {
			lockA.unlock();
			lockB.unlock();
		}
	}

	public void B() {
		lockA.lock();
		lockB.lock();
		try{

			System.out.println("B is Running");
		}catch(Exception e){

		}finally {
			lockA.unlock();
			lockB.unlock();
		}
	}
}

class TestDeadLock{

	public static void main(String[] args) {
//		DeadLock deadLock = new DeadLock();
//		for(int i=0;i<10;i++) {
//			new Thread(()->{
//				deadLock.A();
//			}).start();
//			new Thread(()->{
//				deadLock.B();
//			}).start();
//		}
		Source source = new Source();
		new Thread( () -> {
			try {

				source.lockA();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		},"A").start();
		new Thread( () -> {
			try {
				source.lockB();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		},"B").start();


	}
}
